package com.dashu.park.service;

import com.dashu.base.enums.BusinessType;
import com.dashu.base.enums.ReplRyCode;
import com.dashu.base.enums.common.CompanyType;
import com.dashu.base.utils.CopyUtil;
import com.dashu.base.utils.UIDUtil;
import com.dashu.base.utils.VerificationUtil;
import com.dashu.park.dto.company.EnterpriseDTO;
import com.dashu.park.handler.VerificationException;
import com.dashu.park.model.Enterprise;
import com.dashu.park.model.QEnterprise;
import com.dashu.park.result.PageEnty;
import com.dashu.park.vo.UpdateEntityVO;
import com.dashu.park.vo.company.EnterpriseListVO;
import com.dashu.park.vo.company.EnterpriseVO;
import com.dashu.park.vo.company.UpEnterpriseVO;
import com.querydsl.core.BooleanBuilder;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;

import javax.persistence.FlushModeType;
import javax.transaction.Transactional;
import java.util.Date;
import java.util.List;

@Slf4j
@Service
public class EnterpriseService extends DataService {


    @Transactional
    public EnterpriseDTO add(EnterpriseVO enterpriseVO) {
        Enterprise enterprise = CopyUtil.copyEnty(enterpriseVO, Enterprise.class);
        try {
            long userId = Long.parseLong(VerificationUtil.getUserId());
            enterprise.setId(UIDUtil.nextId());
            enterprise.setCreateUser(userId);
            enterprise.setCreateTime(System.currentTimeMillis());
            enterprise.setBaseId(userId);
            entityManager.persist(enterprise);
//            entityManager.flush();
            entityManager.setFlushMode(FlushModeType.AUTO);
        } catch (Exception e) {
            e.printStackTrace();
            throw new VerificationException(ReplRyCode.DATA_NOT_INVALID, ReplRyCode.DATA_NOT_INVALID.getMessage());
        }
        EnterpriseDTO enterpriseDTO = CopyUtil.copyEnty(enterprise, EnterpriseDTO.class);
        return enterpriseDTO;
    }

    @Transactional
    public EnterpriseDTO updataByEnterpriseId(UpdateEntityVO<UpEnterpriseVO> updateEnterpriseVO) throws Exception {
        QEnterprise qEnterprise = QEnterprise.enterprise;
        long userId = Long.parseLong(VerificationUtil.getUserId());
        UpEnterpriseVO upEnterpriseVO = updateEnterpriseVO.getEntityVO();
        EnterpriseDTO enterpriseDTO = existByCompanyName(upEnterpriseVO.getEnterpriseName(),updateEnterpriseVO.getId());
        if (enterpriseDTO != null) {
            throw new VerificationException(ReplRyCode.EXIST_COMPANY, ReplRyCode.EXIST_COMPANY.getMessage());
        }
        BooleanBuilder booleanBuilder = new BooleanBuilder();
        booleanBuilder.and(qEnterprise.id.eq(updateEnterpriseVO.getId()));
        Enterprise enterprise = queryFactory
                .select(qEnterprise)
                .from(qEnterprise)
                .where(booleanBuilder.getValue()).fetchOne();
        if (enterprise == null)
            throw new VerificationException(ReplRyCode.COMPANY_NOT_DATA, ReplRyCode.COMPANY_NOT_DATA.getMessage());
        enterprise.setUpdateUser(userId);
        enterprise.setUpdateTime(new Date().getTime());
        if (upEnterpriseVO.getAddress() != null)
            enterprise.setAddress(upEnterpriseVO.getAddress());
        if (upEnterpriseVO.getBusinessType() != null)
            enterprise.setBusinessType(BusinessType.map.get(upEnterpriseVO.getBusinessType()));
        if (upEnterpriseVO.getEnterpriseName() != null)
            enterprise.setEnterpriseName(upEnterpriseVO.getEnterpriseName());
        if (upEnterpriseVO.getEnterpriseName() != null)
            enterprise.setEnterpriseType(CompanyType.map.get(upEnterpriseVO.getEnterpriseType()));
        if (upEnterpriseVO.getX() != null)
            enterprise.setX(upEnterpriseVO.getX());
        if (upEnterpriseVO.getY() != null)
            enterprise.setY(upEnterpriseVO.getY());
        if (upEnterpriseVO.getCity() != null)
            enterprise.setCity(upEnterpriseVO.getCity());
        if (upEnterpriseVO.getProvince() != null)
            enterprise.setProvince(upEnterpriseVO.getProvince());
        enterprise = entityManager.merge(enterprise);
//        entityManager.flush();
        entityManager.setFlushMode(FlushModeType.AUTO);
        EnterpriseDTO enterpriseDTO1 = CopyUtil.copyEnty(enterprise, EnterpriseDTO.class);
        return enterpriseDTO1;

    }

    @Transactional
    public boolean deleteByEnterpriseId(long enterpriseDepartmentId) throws Exception {
        QEnterprise qEnterprise = QEnterprise.enterprise;
//        List<CompanyDepartment> companyDepartments = companyDepartmentService.findByCompanyId(enterpriseDepartmentId);
//        if (companyDepartments.size() > 0)
//            throw new VerificationException(ReplRyCode.EXIST_GL_DEPARTMENT, ReplRyCode.EXIST_GL_DEPARTMENT.getMessage());
        BooleanBuilder booleanBuilder = new BooleanBuilder();
        booleanBuilder.and(qEnterprise.id.eq(enterpriseDepartmentId));
        Enterprise enterprise
                = queryFactory
                .select(qEnterprise)
                .from(qEnterprise)
                .where(booleanBuilder.getValue())
                .fetchOne();
        if (enterprise == null) {
            throw new VerificationException(ReplRyCode.COMPANY_NOT_DATA, ReplRyCode.COMPANY_NOT_DATA.getMessage());
        }
        entityManager.remove(enterprise);
//            entityManager.flush();
        entityManager.setFlushMode(FlushModeType.AUTO);
        return true;
    }



    public List<EnterpriseDTO> findByEnterpriseName(String enterpriseName, long baseId) {
        QEnterprise qEnterprise = QEnterprise.enterprise;
        BooleanBuilder booleanBuilder = new BooleanBuilder();
        if (admin != baseId)
            booleanBuilder.and(qEnterprise.baseId.eq(baseId));
        booleanBuilder.and(qEnterprise.enterpriseName.like("%" + enterpriseName + "%"));
        List<Enterprise> enterprises = queryFactory
                .select(qEnterprise)
                .from(qEnterprise)
                .where(booleanBuilder.getValue()).fetch();
        if (enterprises == null)
            throw new VerificationException(ReplRyCode.COMPANY_NOT_DATA, ReplRyCode.COMPANY_NOT_DATA.getMessage());
        List<EnterpriseDTO> enterpriseDTOS = CopyUtil.copyList(enterprises, EnterpriseDTO.class);
        return enterpriseDTOS;

    }

    public List<EnterpriseDTO> findByCreteUser(PageEnty<Long> baseVo) {
        QEnterprise qEnterprise = QEnterprise.enterprise;
        BooleanBuilder booleanBuilder = new BooleanBuilder();
        booleanBuilder.and(qEnterprise.createUser.eq(baseVo.getBaseId()));
        List<Enterprise> enterprises = queryFactory
                .select(qEnterprise)
                .from(qEnterprise)
                .where(booleanBuilder.getValue())
                .fetch();
        List<EnterpriseDTO> recycleDTOS = CopyUtil.copyList(enterprises, EnterpriseDTO.class);
        return recycleDTOS;

    }

    public EnterpriseDTO findByEnterpriseId(long enterpriseId) {
        QEnterprise qEnterprise = QEnterprise.enterprise;
        BooleanBuilder booleanBuilder = new BooleanBuilder();
        booleanBuilder.and(qEnterprise.id.eq(enterpriseId));
        Enterprise enterprise = queryFactory
                .select(qEnterprise)
                .from(qEnterprise)
                .where(booleanBuilder.getValue()).fetchOne();
        if (enterprise == null)
            throw new VerificationException(ReplRyCode.COMPANY_NOT_DATA, ReplRyCode.COMPANY_NOT_DATA.getMessage());
        EnterpriseDTO copyEnty = CopyUtil.copyEnty(enterprise, EnterpriseDTO.class);
        return copyEnty;

    }

    public EnterpriseDTO existByCompanyName(String enterpriseName, long enterpriseId) {
        QEnterprise qEnterprise = QEnterprise.enterprise;
        BooleanBuilder booleanBuilder = new BooleanBuilder();
        booleanBuilder.and(qEnterprise.enterpriseName.eq(enterpriseName));
        if (enterpriseId != 0)
            booleanBuilder.and(qEnterprise.id.notIn(enterpriseId));
        Enterprise enterprise = queryFactory
                .select(qEnterprise)
                .from(qEnterprise)
                .where(booleanBuilder.getValue()).fetchOne();
        EnterpriseDTO enterpriseDTO = CopyUtil.copyEnty(enterprise, EnterpriseDTO.class);
        return enterpriseDTO;

    }

    public void isAdd(EnterpriseVO enterpriseVO) {
        QEnterprise qEnterprise = QEnterprise.enterprise;
        BooleanBuilder booleanBuilder = new BooleanBuilder();
        booleanBuilder.and(qEnterprise.enterpriseNum.eq(enterpriseVO.getEnterpriseNum()));
        Enterprise enterprise = queryFactory
                .select(qEnterprise)
                .from(qEnterprise)
                .where(booleanBuilder.getValue()).fetchOne();
        if (enterprise != null)
            throw new VerificationException(ReplRyCode.EXIST_COMPANY_NUM, ReplRyCode.EXIST_COMPANY_NUM.getMessage());
    }

    public long enterpriseCount(PageEnty<EnterpriseListVO> enterprisePageEntyVO) throws Exception {
        QEnterprise qEnterprise = QEnterprise.enterprise;
        long userId = Long.parseLong(VerificationUtil.getUserId());
        if (enterprisePageEntyVO.getVo() == null)
            throw new VerificationException(ReplRyCode.DATA_ERROR, ReplRyCode.DATA_ERROR.getMessage());
        EnterpriseListVO enterpriseListVO = enterprisePageEntyVO.getVo();
        BooleanBuilder booleanBuilder = new BooleanBuilder();
        long baseId = enterprisePageEntyVO.getBaseId() == 0 ? userId : enterprisePageEntyVO.getBaseId();
        if (admin != baseId) {
            booleanBuilder.and(qEnterprise.baseId.eq(baseId));
        }
        if (!StringUtils.isEmpty(enterpriseListVO.getBusinessType()))
            booleanBuilder.and(qEnterprise.businessType.eq(BusinessType.map.get(enterpriseListVO.getBusinessType())));
        if (!StringUtils.isEmpty(enterpriseListVO.getEnterpriseName()))
            booleanBuilder.and(qEnterprise.enterpriseName.eq(enterpriseListVO.getEnterpriseName()));
        long count = queryFactory
                .select(qEnterprise)
                .from(qEnterprise)
                .where(booleanBuilder.getValue())
                .fetchCount();
        return count;
    }

    public List<EnterpriseDTO> pageEnterpriseList(PageEnty<EnterpriseListVO> enterprisePageEntyVO) throws Exception {
        QEnterprise qEnterprise = QEnterprise.enterprise;
        long userId = Long.parseLong(VerificationUtil.getUserId());
        if (enterprisePageEntyVO.getVo() == null)
            throw new VerificationException(ReplRyCode.DATA_ERROR, ReplRyCode.DATA_ERROR.getMessage());
        EnterpriseListVO enterpriseListVO = enterprisePageEntyVO.getVo();
        BooleanBuilder booleanBuilder = new BooleanBuilder();
        long baseId = enterprisePageEntyVO.getBaseId() == 0 ? userId : enterprisePageEntyVO.getBaseId();
        if (admin != baseId) {
            booleanBuilder.and(qEnterprise.baseId.eq(baseId));
        }
        if (!StringUtils.isEmpty(enterpriseListVO.getBusinessType()))
            booleanBuilder.and(qEnterprise.businessType.eq(BusinessType.map.get(enterpriseListVO.getBusinessType())));
        if (!StringUtils.isEmpty(enterpriseListVO.getEnterpriseName()))
            booleanBuilder.and(qEnterprise.enterpriseName.eq(enterpriseListVO.getEnterpriseName()));
        List<Enterprise> enterprises = queryFactory
                .select(qEnterprise)
                .from(qEnterprise)
                .where(booleanBuilder.getValue())
                .offset((enterprisePageEntyVO.getPage() - 1) * enterprisePageEntyVO.getNum())
                .limit(enterprisePageEntyVO.getNum())
                .orderBy(qEnterprise.createTime.desc())
                .fetch();
        if (enterprises == null)
            throw new VerificationException(ReplRyCode.COMPANY_NOT_DATA, ReplRyCode.COMPANY_NOT_DATA.getMessage());
        List<EnterpriseDTO> enterpriseDTOS = CopyUtil.copyList(enterprises, EnterpriseDTO.class);
        return enterpriseDTOS;

    }

    public List<Enterprise> findByBaseId(long baseId) {
        QEnterprise qEnterprise = QEnterprise.enterprise;
        BooleanBuilder booleanBuilder = new BooleanBuilder();
        if (admin != baseId)
            booleanBuilder.and(qEnterprise.baseId.eq(baseId));
        List<Enterprise> enterprises = queryFactory
                .select(qEnterprise)
                .from(qEnterprise)
                .where(booleanBuilder.getValue())
                .fetch();
        return enterprises;

    }

}
